#include "animatestackedwidget.h"
#include"QPainter"
#include<QPropertyAnimation>
AnimateStackedWidget::AnimateStackedWidget(QWidget *parent)
    :QStackedWidget(parent)
{
    m_pageindex=0;  // 初始化当前页面索引为 0
    m_isAnimating=false;    // 初始化动画状态为 false，表示没有动画进行中
}

AnimateStackedWidget::~AnimateStackedWidget()
{

}

// 自定义的绘制事件，负责绘制动画效果
void AnimateStackedWidget::paintEvent(QPaintEvent *event)
{
    QPainter p(this);  // 创建一个 QPainter 对象 p，用于在当前控件上绘制，p 是绘制的工具

    // 判断当前旋转角度是否在 0 到 90 度之间
    if (m_rotateVal > 0 && m_rotateVal <= 90) {
        QPixmap pix(currentWidget()->size());   // 创建一个与当前页面大小相同的 QPixmap 对象（缓存当前页面内容）
        currentWidget()->render(&pix);  // 将当前页面渲染到 QPixmap 中，pix 存储当前页面的图像

        // 创建一个 QTransform 对象，用于旋转和移动图片
        QTransform transform;
        transform.translate(width()/2, 0);  // 平移坐标系原点到控件的中心，旋转会围绕这个点进行
        transform.rotate(m_rotateVal, Qt::YAxis);   // 沿 Y 轴旋转 m_rotateVal 角度，旋转当前页面
        p.setTransform(transform);  // 应用旋转变换，p 设置为旋转后的状态

        // 将旋转后的图像绘制到控件上，图像的左上角位置会根据平移来保证图片居中显示
        p.drawPixmap(-width()/2, 0, pix);  // 将图像绘制到左上角，偏移量为 -width()/2 保证旋转中心对准控件中心
    } else if (m_rotateVal > 90 && m_rotateVal <= 180) {
        // 如果旋转角度在 90° 到 180° 之间，处理翻转到背面的效果
        QPixmap pix(widget(m_pageindex)->size());  // 创建一个与目标页面大小相同的 QPixmap 对象
        widget(m_pageindex)->render(&pix);  // 渲染目标页面的内容到 pix 中

        // 创建旋转变换
        QTransform transform;
        transform.translate(width()/2, 0);  // 将坐标系原点平移到控件的中心，旋转会围绕这个点
        transform.rotate(m_rotateVal + 180, Qt::YAxis);  // 旋转角度增加 180°，达到从正面翻转到背面的效果
        p.setTransform(transform);  // 应用旋转变换

        // 绘制旋转后的图像
        p.drawPixmap(-width()/2, 0, pix);  // 在指定位置绘制图像，确保图像居中显示
    }
    else if (m_rotateVal > -180 && m_rotateVal <= -90) { // 反向旋转，旋转角度从 -180° 到 -90° 之间
        QPixmap pix(widget(m_pageindex)->size());  // 获取目标页面的 QPixmap 缓存
        widget(m_pageindex)->render(&pix);  // 渲染目标页面内容到 pix 中

        // 创建旋转变换
        QTransform transform;
        transform.translate(width()/2, 0);  // 平移坐标系原点到控件的中心
        transform.rotate(m_rotateVal + 180, Qt::YAxis);  // 旋转角度加 180°，模拟从背面翻转回正面
        p.setTransform(transform);  // 应用旋转变换

        // 绘制旋转后的图像
        p.drawPixmap(-width()/2, 0, pix);  // 在指定位置绘制图像
    } else if (m_rotateVal > -90 && m_rotateVal < 0) {
        // 处理从负角度 -90° 到 0° 之间的旋转
        QPixmap pix(currentWidget()->size());  // 获取当前页面的 QPixmap 缓存
        currentWidget()->render(&pix);  // 渲染当前页面内容到 pix 中

        // 创建旋转变换
        QTransform transform;
        transform.translate(width()/2, 0);  // 平移坐标系原点到控件的中心
        transform.rotate(m_rotateVal, Qt::YAxis);  // 沿 Y 轴旋转 m_rotateVal 角度
        p.setTransform(transform);  // 应用旋转变换

        // 绘制旋转后的图像
        p.drawPixmap(-width()/2, 0, pix);  // 在指定位置绘制图像，确保图像居中显示
    }
}


// 动画启动函数，负责触发翻页动画
void AnimateStackedWidget::animation(int index)
{
    m_pageindex=index;  // 设置目标页面的索引
    m_isAnimating = true;   // 设置动画状态为正在进行
    QPropertyAnimation *animation=new QPropertyAnimation(this,"rotateVal");// 创建旋转角度的动画

    //设置动画持续时间
    animation->setDuration(700);

    animation->setEasingCurve(QEasingCurve::Linear);// 设置动画的缓和曲线为线性，表示匀速进行

    //设置动画起始值
    animation->setStartValue(m_startVal);

    //设置动画结束值
    animation->setEndValue(m_endVal);

    // 连接信号槽，当动画的值发生变化时调用 onValueChanged，完成重绘
    QObject::connect(animation,&QPropertyAnimation::valueChanged,this,&AnimateStackedWidget::onValueChanged);
    // 连接信号槽，当动画完成时调用 onFinished，完成页面切换
    QObject::connect(animation,&QPropertyAnimation::finished,this,&AnimateStackedWidget::onFinished);

    // 隐藏当前页面，在动画过程中不显示当前页面
    currentWidget()->hide();

    // 启动动画
    animation->start();
}

void AnimateStackedWidget::onValueChanged()
{
    // 每当动画值变化时，重新绘制页面，更新旋转角度
    repaint();
}

void AnimateStackedWidget::onFinished()
{
    //动画结束
    widget(m_pageindex)->show();
    widget(m_pageindex)->raise();

    setCurrentWidget(widget(m_pageindex));
}
